home *** CD-ROM | disk | FTP | other *** search
- ; Wb-tree File Based Associative String Data Base System.
- ; Copyright (c) 1991, 1992, 1993 Holland Mark Martin
- ;
- ;Permission to use, copy, modify, and distribute this software and its
- ;documentation for educational, research, and non-profit purposes and
- ;without fee is hereby granted, provided that the above copyright
- ;notice appear in all copies and that both that copyright notice and
- ;this permission notice appear in supporting documentation, and that
- ;the name of Holland Mark Martin not be used in advertising or
- ;publicity pertaining to distribution of the software without specific,
- ;written prior consent in each case. Permission to incorporate this
- ;software into commercial products can be obtained from Jonathan
- ;Finger, Holland Mark Martin, 174 Middlesex Turnpike, Burlington, MA,
- ;01803-4467, USA. Holland Mark Martin makes no representations about
- ;the suitability or correctness of this software for any purpose. It
- ;is provided "as is" without express or implied warranty. Holland Mark
- ;Martin is under no obligation to provide any services, by way of
- ;maintenance, update, or otherwise.
-
-
- ;minimum is 1
- (define NUM-SEGS 10)
-
- ;minumum FLC-LEN is 10
- ;This coresponds to 2 times the maximum number of
- ;blocks which would ever be needed for a FREELIST split.
- (define FLC-LEN 20)
-
- ;amount to increase the ENT-TAB by when allocating buffers.
- (define ENT-TAB-INC 512)
-
- ;;;; ERROR Return Codes
-
- (define SUCCESS 0) ; successful execution
- (define NOTPRES -1) ; successful execution, no data present or no change made
- (define TERMINATED -2) ; failure, no damage, caller can retry operation
- (define RETRYERR -10) ; failure, no damage, caller can retry operation
- (define ARGERR -15) ; failure, no damage, call was in error
- (define NOROOM -20) ; failure, no damage, out of room in file
- (define TYPERR -30) ; failure, file or object was not of correct type
- (define IOERR -40) ; i/o error, DB may be damaged
- (define STRANGERR -45) ; internal error, DB may be damaged
- (define UNKERR -90) ; placeholder code
- (define MAXERR -100)
-
- ;; return error code if a valid error code (-1..MAXERR) else false (0)
- (define (err? x)
- (and (number? x) (negative? x) (>= x MAXERR) x))
-
- (define (realerr? x)
- (and (number? x) (<= x RETRYERR) (>= x MAXERR) x))
-
- (define (success? x)
- (not (err? x)))
-
- ;;;; BLK parameters
-
- ;;; The IDs are 4 byte numbers identifying this block, the root of
- ;;; this tree, and the next in the chain.
- (define BLK-ID-POS 0)
- (define BLK-TOP-ID-POS 4)
- (define BLK-NXT-ID-POS 8)
- (define BLK-TIME-POS 12)
- ;;; blk-end-pos is position (stored in 2 bytes) of first free byte
- (define BLK-END-POS 16)
- (define BLK-LEVEL-POS 18)
- (define BLK-TYP-POS 19)
- (define BLK-DATA-START 20)
-
- (define (BLK-ID blk) (str2long blk BLK-ID-POS))
- (define (BLK-TOP-ID blk) (str2long blk BLK-TOP-ID-POS))
- (define (BLK-NXT-ID blk) (str2long blk BLK-NXT-ID-POS))
- (define (BLK-TIME blk) (str2long blk BLK-TIME-POS))
- (define (BLK-END blk) (str2short blk BLK-END-POS))
- (define (BLK-LEVEL b) (char->integer (string-ref b BLK-LEVEL-POS)))
- (define (BLK-TYP b) (string-ref b BLK-TYP-POS))
- (define (BLK-TYP? b typ) (char=? (string-ref b BLK-TYP-POS) typ))
-
- (define (BLK-SET-ID! blk id) (long2str! blk BLK-ID-POS id))
- (define (BLK-SET-TOP-ID! blk id) (long2str! blk BLK-TOP-ID-POS id))
- (define (BLK-SET-NXT-ID! blk id) (long2str! blk BLK-NXT-ID-POS id))
- (define (BLK-SET-TIME! blk tim) (long2str! blk BLK-TIME-POS tim))
- (define (BLK-SET-END! blk pos) (short2str! blk BLK-END-POS pos))
- (define (BLK-SET-LEVEL! b level)
- (string-set! b BLK-LEVEL-POS (integer->char level)))
- (define (BLK-SET-TYP! b typ) (string-set! b BLK-TYP-POS typ))
-
- (define LEAF (char->integer #\0))
-
- (define DIR-TYP #\D)
- (define IND-TYP #\T)
- (define SEQ-TYP #\S)
- (define FRL-TYP #\F)
-
- (define WCB-SAP 1)
- (define WCB-SAR 2)
- (define WCB-SAC 4)
- (define WCB-FAC 8)
-
- (define (WCB-SAP? wcb) (not (zero? (logand WCB-SAP wcb))))
- (define (WCB-SAR? wcb) (not (zero? (logand WCB-SAR wcb))))
- (define (WCB-SAC? wcb) (not (zero? (logand WCB-SAC wcb))))
- (define (WCB-FAC? wcb) (not (zero? (logand WCB-FAC wcb))))
-
- (define END-OF-CHAIN -1)
- (define START-OF-CHAIN -2)
-
- (define (FIELD-LEN blk pos)
- (char->integer (string-ref blk pos)))
-
- (define (SET-FIELD-LEN! blk pos len)
- (string-set! blk pos (integer->char len)))
-
- ;;; This is dangerous. At the moment all occurences of next-field
- ;;; have simple expressions for the second argument.
-
- (define (next-field blk pos)
- (+ (FIELD-LEN blk pos) pos 1))
-
- (define (NEXT-CNVPAIR blk pos)
- (next-field blk (next-field blk (+ 1 pos))))
-
- (define (LEAF? blk) (= (BLK-LEVEL blk) LEAF))
-
- ;;; LCK and ENT tables
-
- ;;; If you change this change amnesia-ent!
- ;;; This depends on seg never being less than -1
- (define (HASH2INT seg num)
- (remainder (+ (* seg 97) num (* num-buks (+ 1 (quotient 97 num-buks))))
- num-buks))
-
- ;;; Called with SEG-LCK locked.
- ;;; If you don't know what you are doing. DON'T DO IT!
- ;;; Compute inverse hash function so that ent can still be found.
- (define (amnesia-ent! ent)
- (ENT-SET-ID! ent (HASH2INT (+ 1 (ENT-SEG ent)) (ENT-ID ent)))
- (ENT-SET-DTY! ent #f) ;so block will not be written out when released.
- (ENT-SET-PUS! ent 0)
- (if (ENT-BLK ent)
- (if (BLK-TYP? (ENT-BLK ent) DIR-TYP)
- (BLK-SET-TYP! (ENT-BLK ent) IND-TYP))) ; avoid useless warnings or writes
- (ENT-SET-SEG! ent -1)
- (ENT-SET-AGE! ent 128))
-
- (define (SAME-BUK? a-seg a-num b-seg b-num)
- (= (HASH2INT a-seg a-num) (HASH2INT b-seg b-num)))
-
- (define (GET-BUK seg blk-num)
- (vector-ref buk-tab (HASH2INT seg blk-num)))
-
- ;;; doesnt wait, ie, returns #F is busy
- (define (GET-BUK-LCK seg blk-num)
- (try-lck (vector-ref lck-tab (HASH2INT seg blk-num))))
-
- (define (GET-BUK-WAIT seg blk-num)
- (lck! (vector-ref lck-tab (HASH2INT seg blk-num)))
- (vector-ref buk-tab (HASH2INT seg blk-num)))
-
- (define (REL-BUK! seg blk-num)
- (unlck! (vector-ref lck-tab (HASH2INT seg blk-num))))
-
- ;;; SET-BUK! assumes BUK is already lcked by caller
- (define (SET-BUK! seg blk-num ent)
- (vector-set! buk-tab (HASH2INT seg blk-num) ent))
-
- (define ACCREAD 'ACCREAD)
- (define ACCWRITE 'ACCWRITE)
- (define ACCPEND 'ACCPEND)
-
- ;;;; Routines for finding the appropriate BLK for an operation.
- ;;; PACKETs used to return multiple values from chain-find.
- ;;; and various other operations
-
- (define PKT-SIZE 6)
-
- (define (MATCH-TYPE p) (vector-ref p 0)) ;see below for PASTP, QPASTP,...
- (define (MATCH-POS p) (vector-ref p 1)) ;position of key we (almost) matched.
- (define (KEY-POS p) (vector-ref p 2)) ;number of matching characters
- (define (PREV-MATCH-POS p) (vector-ref p 3)) ;position of PREVIOUS key we (almost) matched.
- (define (BLK-TO-CACHE p) (vector-ref p 4)) ;blk number to cache
- (define (SUCCESS-CODE p) (vector-ref p 5)) ;UNUSED
-
- (define (SET-MATCH-TYPE! p v) (vector-set! p 0 v))
- (define (SET-MATCH-POS! p v) (vector-set! p 1 v))
- (define (SET-KEY-POS! p v) (vector-set! p 2 v))
- (define (SET-PREV-MATCH-POS! p v) (vector-set! p 3 v)) ;position of PREVIOUS key we (almost) matched.
- (define (SET-BLK-TO-CACHE! p v) (vector-set! p 4 v)) ;blk number to cache
- (define (SET-SUCCESS-CODE! p v) (vector-set! p 5 v)) ;UNUSED
-
- (define (PACK! p type b-pos k-pos p-pos)
- (SET-MATCH-TYPE! p type)
- (SET-MATCH-POS! p b-pos)
- (SET-KEY-POS! p k-pos)
- (SET-PREV-MATCH-POS! p p-pos))
-
- (define PASTP 'PASTP) ;not exact match;repeat count of next key will change.
- ;match(new-key, after-key) > repeatcount(after-key)
- (define QPASTP 'QPASTP) ;not exact match;repeat count of next key will not change.
- ;match(new-key, after-key) <= repeatcount(after-key)
- (define MATCH 'MATCH) ;exact match (not split key).
- (define MATCHEND 'MATCHEND) ;matched split key.
- (define PASTEND 'PASTEND) ;greater than split key.
-
- (define REM-SCAN -1) ;operation codes for SCAN
- (define COUNT-SCAN 0)
- (define MODIFY-SCAN 1)
-
- (define SKEY-COUNT MATCH-POS) ;aliased function names for SCAN
- (define SET-SKEY-COUNT! SET-MATCH-POS!)
- (define SKEY-LEN KEY-POS)
- (define SET-SKEY-LEN! SET-KEY-POS!)
-
- (define (SEG-PORT seg) (SEGD-PORT (vector-ref segd-tab seg)))
- (define (SEG-BSIZ seg) (SEGD-BSIZ (vector-ref segd-tab seg)))
- (define (SEG-USED seg) (SEGD-USED (vector-ref segd-tab seg)))
- (define (SEG-STR seg) (SEGD-STR (vector-ref segd-tab seg)))
- (define (SEG-RT-HAN seg) (SEGD-RT-HAN (vector-ref segd-tab seg)))
- (define (SEG-FL-HAN seg) (SEGD-FL-HAN (vector-ref segd-tab seg)))
- (define (SEG-LCK seg) (SEGD-LCK (vector-ref segd-tab seg)))
- (define (SEG-FCK seg) (SEGD-FCK (vector-ref segd-tab seg)))
- (define (SEG-FLC-LEN seg) (SEGD-FLC-LEN (vector-ref segd-tab seg)))
- (define (SEG-FLC seg) (SEGD-FLC (vector-ref segd-tab seg)))
-
- (define (SEG-SET-PORT! seg port) (SEGD-SET-PORT! (vector-ref segd-tab seg) port))
- (define (SEG-SET-BSIZ! seg bsiz) (SEGD-SET-BSIZ! (vector-ref segd-tab seg) bsiz))
- (define (SEG-SET-USED! seg used) (SEGD-SET-USED! (vector-ref segd-tab seg) used))
- (define (SEG-SET-STR! seg str) (SEGD-SET-STR! (vector-ref segd-tab seg) str))
- (define (SEG-SET-FLC-LEN! seg flc-len) (SEGD-SET-FLC-LEN! (vector-ref segd-tab seg) flc-len))
- (define (SEG-SET-FLC! seg flc) (SEGD-SET-FLC! (vector-ref segd-tab seg) flc))
-